package com.eliaukjq.jihe;

import java.util.ArrayList;

public class EnsureCapacityExample {
    public static void main(String[] args) {
        int elementsToAdd = 100;
        ArrayList<Integer> list = new ArrayList<>();

        // 提前确保容量
        list.ensureCapacity(elementsToAdd);

        // 添加元素
        for (int i = 0; i < elementsToAdd; i++) {
            list.add(i);
        }

        // 打印出添加的元素和ArrayList的实际容量
        System.out.println("List size: " + list.size());
        System.out.println("Internal capacity of the ArrayList: " + getArrayListCapacity(list));
    }

    // 使用反射来检查ArrayList的容量
    /**
     * 获取ArrayList的实际容量。
     * 通过反射访问ArrayList的私有成员elementData，以获取其实际存储数组的长度。
     * 这对于了解ArrayList在扩展时何时重新分配空间以及如何优化其大小预分配很有用。
     *
     * @param arrayList 要查询容量的ArrayList对象。
     * @return ArrayList的实际容量。如果无法通过反射访问或获取长度，则返回-1。
     */
    private static int getArrayListCapacity(ArrayList<?> arrayList) {
        try {
            // 通过反射获取ArrayList类中声明的私有字段elementData
            java.lang.reflect.Field dataField = ArrayList.class.getDeclaredField("elementData");
            // 设置elementData字段可访问，以绕过Java的访问控制
            dataField.setAccessible(true);
            // 获取elementData字段的值，它是一个Object数组，长度即为ArrayList的实际容量
            return ((Object[]) dataField.get(arrayList)).length;
        } catch (Exception e) {
            // 如果在反射过程中发生异常，打印堆栈跟踪并返回-1作为错误指示
            e.printStackTrace();
            return -1;
        }

    }
}